package com.fengxing.ams.pub.util;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

public class MiscUtils {
	private static Logger logger = Logger.getLogger(MiscUtils.class);
	
	/**
	 * @return The local server ip.
	 */
	public static String getServerIP() {
        String localIp = null;
        try {
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface ni = netInterfaces.nextElement();
                Enumeration<InetAddress> address = ni.getInetAddresses();
                while (address.hasMoreElements()) {
                    InetAddress ip = address.nextElement();
                    if (!ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) {
                        if (!ip.isSiteLocalAddress()) { 
                            String netIp = ip.getHostAddress();
                            if (StringUtils.isNotBlank(netIp)) {
                                return netIp;
                            }
                        } else {
                            localIp = ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (SocketException e) {
            logger.error("get host ip is error.", e);
        }
        return localIp;
	}
	
	/**
	 * Check if the given localIP is valid according to the configured ips.
	 * The last section of configured ips can be wildcard characters or an ip range.
	 * e.g. 157.241.136.*  /  157.241.136.10-25
	 * 
	 * @param localIP
	 * @param configuredIps
	 * @return
	 */
	public static boolean isIPValid(String localIP, String[] configuredIps) {
        return isIPValid(localIP, configuredIps, true);
    }
	
	/**
     * Check if the given localIP is valid according to the configured ips, if the configured ips are empty,
     * then the default value will be returned.
     * The last section of configured ips can be wildcard characters or an ip range.
     * e.g. 157.241.136.*  /  157.241.136.10-25
     * 
     * @param localIP
     * @param configuredIps
     * @param defaultValue
     * @return
     */
	public static boolean isIPValid(String localIP, String[] configuredIps, boolean defaultValue) {
	    if (ArrayUtils.isEmpty(configuredIps)) {
            return defaultValue;
        }
        for (String server : configuredIps) {
            server = server.trim();
            if (server.endsWith("*")) {
                // 157.241.136.*
                if (localIP.startsWith(server.substring(0, server.length() - 1))) {
                    return true;
                }
            } else if (server.indexOf("-") > 0 && server.indexOf(".") > 0) {
                // 157.241.136.10-25
                String ipPrefix = server.substring(0, server.lastIndexOf(".") + 1);
                String ipStart = server.substring(server.lastIndexOf(".") + 1, server.indexOf("-"));
                String ipEnd = server.substring(server.indexOf("-") + 1);
                try {
                    int start = Integer.valueOf(ipStart);
                    int end = Integer.valueOf(ipEnd);
                    for (int i = start; i <= end; i++) {
                        if (localIP.equals(ipPrefix + i)) {
                            return true;
                        }
                    }
                } catch (NumberFormatException e) {
                    logger.warn("The server of initialization config is invalid:"
                            + StringUtils.join(configuredIps, ","));
                }
            } else if (localIP.equals(server)) {
                return true;
            }
        }
        return false;
	}
}
